package persistency;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import model.Business;
import model.BusinessTypeEnum;
import model.Course;
import model.CourseHistory;
import model.FreeStudent;
import model.OfferedCourse;
import model.Registration;
import model.RetrainingStudent;
import model.Student;
import model.Teacher;
import model.enums.Classroom;
import persistency.controller.CourseController;
import persistency.controller.OfferedCourseController;
import persistency.controller.StudentController;
import persistency.controller.TeacherController;
import util.TimeBlock;
import util.enums.CourseDay;

public class DBFacade {
	private static DBConnection connection;
	private ResultSet resultSet;

	public DBFacade() {
		if (connection == null) {
			connection = new MySQLConnection();
		}
	}

	public Collection<Business> getResult(BusinessTypeEnum business, String sql, Object[] args, int[] argTypes, ArgIO[] argsIO) {
		List<Business> list = new ArrayList<Business>();
		// TableMetaDataProps properties = new TableMetaDataProps();
		Business object = null;

		try {
			resultSet = connection.getResultset(sql, args, argTypes, argsIO);
			// ResultSetMetaData rsmd = resultSet.getMetaData();
			while (resultSet.next()) {
				object = createBusinessObject(business, resultSet);
				list.add(object);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return list;
	}

	public Collection<Business> getResult(BusinessTypeEnum business, String sql) {
		List<Business> list = new ArrayList<Business>();
		// TableMetaDataProps properties = new TableMetaDataProps();
		Business object = null;
		
		try {
			resultSet = connection.getResultset(sql);
			// ResultSetMetaData rsmd = resultSet.getMetaData();
			while (resultSet.next()) {
				object = createBusinessObject(business, resultSet);
				list.add(object);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return list;
	}
	
	public int executeMaxQuery(String sql){
		int object = 0;
		try {
			resultSet = connection.getResultset(sql);
			// ResultSetMetaData rsmd = resultSet.getMetaData();
			while(resultSet.next()){
				object = resultSet.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return object;
	}

	/**
	 * Removes one business object
	 * 
	 * @param sql
	 * @param args
	 * @param argTypes
	 * @param argsIO
	 * @return
	 */
	public boolean removeBusinessObject(String sql, Object[] args, int[] argTypes, ArgIO[] argsIO) {
		return connection.removeBusinessObject(sql, args, argTypes, argsIO);
	}

	/**
	 * create a business object of type BusinessTypeEnum
	 * 
	 * @param business
	 * @param result
	 * @return
	 */
	private Business createBusinessObject(BusinessTypeEnum business, ResultSet result) {
		Business object = null;

		try {
			object = createBusinessObject(business, result, object);
		} catch (SQLException exp) {
			exp.printStackTrace();
		}
		return object;
	}

	/**
	 * Creates a business object of typ BusinessTypeEnum
	 * 
	 * @param business
	 * @param result
	 * @param object
	 * @return Business
	 * @throws SQLException
	 */
	private Business createBusinessObject(BusinessTypeEnum business, ResultSet result, Business object) throws SQLException {
		switch (business.getSeq()) {
		case 0: {
			object = new Course(result.getInt(1), result.getString(2), result.getInt(3), result.getInt(4));
			break;
		}
		case 1: {
			object = new CourseHistory(StudentController.instance().getStudent(result.getString(1)),CourseController.instance().getCourse(result.getString(2)), result.getString(3), result.getInt(4));
			break;
		}
		case 2: {
			object = new Teacher(result.getString(1), result.getString(2), result.getInt(3));
			break;
		}
		case 3: {
			Student student = StudentController.instance().getStudent(result.getString(1));
			object = new FreeStudent(student.getStudentNumber(),student.getName(), result.getString(2));
			break;
		}
		case 4: {
			Student student = StudentController.instance().getStudent(result.getString(1));
			object = new RetrainingStudent(student.getStudentNumber(),student.getName(), result.getString(2), result.getString(3));
			break;
		}
		case 5: {
			try {
				object = new OfferedCourse(result.getInt(1), CourseController.instance().getCourse(result.getString(2)), Classroom.values()[result.getInt(3)],TeacherController.instance().getTeacher(result.getString(4)), result.getInt(5), new TimeBlock(CourseDay.valueOf(result.getString(6)),
						result.getString(7)+":"+ result.getString(8),result.getInt(9)));
			} catch (Exception e) {
				e.printStackTrace();
			}

			break;
		}
		case 6: {
			try {
				int id = result.getInt(1);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				
				object = new Registration(id,OfferedCourseController.instance().getOfferedCourseByRegistrationId(""+id), StudentController.instance().getStudent(result.getString(2)), new util.Date(sdf.parse(result.getString(3))));
			} catch (Exception e) {
				e.printStackTrace();
			}
			break;
		}
		case 7: {
			try {
				object = new Student(result.getString(1),result.getString(2));
			} catch (Exception e) {
				e.printStackTrace();
			}
			break;
		}

		}
		return object;
	}

	public boolean createObject(String sql, Object[] args, int[] argTypes, ArgIO[] argsIO) {
		boolean success = false;

		success = connection.createBusinessObject(sql, args, argTypes, argsIO);
		return success;
	}
}
